/**
 * Created by Stanislav Doskalenko on 22.06.17.
 * © 2017-present, doskalenko.s@gmail.com
 */

import React from 'react';
import {ActivityIndicator, Animated, ImageBackground, Image} from 'react-native';
import FastImage from 'react-native-fast-image';
import PropTypes from 'prop-types';

export default class FadeImage extends React.PureComponent {

  static propTypes = {
    source: PropTypes.oneOfType([
      PropTypes.object,
      PropTypes.number
    ]),
    onLoad: PropTypes.func,
    duration: PropTypes.number,
    defaultSource: PropTypes.number,
    onError: PropTypes.func,
    onLoadEnd: PropTypes.func,
    resizeMode: PropTypes.string,
    backgroundColor: PropTypes.string,
    showLoading: PropTypes.bool,
    autoHeight: PropTypes.bool,
  };
  static defaultProps = {
    defaultSource: null,
    showLoading: false,
    backgroundColor: 'transparent',
    autoHeight: false
  };
  imageOpacity = new Animated.Value(0);

  constructor(props) {
    super(props);
    if (this.props.source && this.props.source.uri && this.props.source.uri.length > 0 && this.props.source.uri.indexOf('http') !== -1) {
      FastImage.preload([{uri: this.props.source.uri}]);
    }

    this.state = {loading: true, width: 0, height:0, size: null};
  }

  componentDidMount() {
    if (this.props.style && this.props.style.height) {
      this.setState({height: this.props.style.height});
    }
  }

  onLoadImage = (e) => {
    if (e.nativeEvent.height) {
      if (this.props.onLoad) {
        this.props.onLoad();
      }
      if (this.props.autoHeight) {
        if (this.state.width > 0) {
          //计算
          const ratio = e.nativeEvent.height / e.nativeEvent.width;
          this.setState({height: this.state.width * ratio}, () => {
            this.animate();
          });
        } else {
          this.setState({size: {width: e.nativeEvent.width, height: e.nativeEvent.height}}, () => {
            this.animate();
          });
        }
      }
      else {
        this.animate();
      }
    }
    else {
      this.onError();
    }
  };

  animate = () => {
    if (this.props.showLoading) {
      this.setState({loading: false}, () => {
        Animated.timing(this.imageOpacity, {
          toValue: 1,
          duration: this.props.duration || 250,
          useNativeDriver: true,
        }).start();
      });
    } else {
      Animated.timing(this.imageOpacity, {
        toValue: 1,
        duration: this.props.duration || 250,
        useNativeDriver: true,
      }).start();
    }
  };

  onError = () => {
    if (this.props.onError) {
      this.props.onError();
    }
    if (this.props.showLoading) {
      this.setState({loading: false});
    }
  };

  //http://yx.acoer.cn/goods/goods/api/queryGoodsList?route=goods
  renderIOSImage = () => {
    const showNetImage = (this.props.source && this.props.source.uri && this.props.source.uri.indexOf('http') >= 0);
    const noImage = !this.props.source || !this.props.source.uri || this.props.source.uri.length === 0;
    
    return <Animated.View style={{
      position: 'absolute',
      left: 0,
      top: 0,
      right: 0,
      bottom: 0,
      backgroundColor: this.props.backgroundColor,
      opacity: this.imageOpacity,
      borderRadius: this.props.style.borderRadius,
    }}
    >
      {showNetImage ?
          <FastImage style={{
            position: 'absolute', left: 0, top: 0, right: 0, bottom: 0, borderRadius: this.props.style.borderRadius,
          }}
                     source={this.props.source}
                     ref={this.props.ref}
                     resizeMode={this.props.resizeMode || FastImage.resizeMode.cover}
                     onLoadStart={this.props.onLoadStart}
                     onProgress={this.props.onProgress}
                     onLoad={this.onLoadImage}
                     onError={this.onError}
                     onLoadEnd={this.props.onLoadEnd}
          /> : (!noImage ? <Image style={{
            position: 'absolute', left: 0, top: 0, right: 0, bottom: 0, borderRadius: this.props.style.borderRadius,
          }}
                                  source={this.props.source}
                                  ref={this.props.ref}
                                  resizeMode={this.props.resizeMode || FastImage.resizeMode.cover}
                                  onLoadStart={this.props.onLoadStart}
                                  onProgress={this.props.onProgress}
                                  onLoad={this.onLoadImage}
                                  onError={this.onError}
                                  onLoadEnd={this.props.onLoadEnd}
          /> : null)}

    </Animated.View>;
  };

  render() {
    let style = {
      ...this.props.style,
      height: this.state.height,
    };
    if (this.state.height === 0){
      style = this.props.style;
    }
    return (
        <ImageBackground source={this.props.defaultSource}
                         style={[{justifyContent: 'center', alignItems: 'center'}, style]}
                         resizeMode={this.props.resizeMode || 'cover'}
                         onLayout={(event) => {
                           if (this.props.autoHeight) {
                             let {width} = event.nativeEvent.layout;
                             if (this.state.size) {
                               const ratio = this.state.size.height / this.state.size.width;
                               this.setState({height: width * ratio, width: width});
                             } else {
                               this.setState({width: width});
                             }
                           }
                         }}
        >
          {this.renderIOSImage()}
          {this.props.children}
          {(this.props.showLoading && this.state.loading) ?
              <ActivityIndicator size={'large'} color={'white'} animating={true}/> : null}
        </ImageBackground>
    );
  }
}
